import axios from "axios";
import { ElNotification, ElMessageBox } from "element-plus";
import sysConfig from "@/config";
import tool from "@/utils/tool";
import router from "@/router";

axios.defaults.baseURL = "";

axios.defaults.timeout = sysConfig.TIMEOUT;

// HTTP request 拦截器
axios.interceptors.request.use(
	(config) => {
		let token = tool.data.get("TOKEN");
		if (token) {
			config.headers[sysConfig.TOKEN_NAME] =
				sysConfig.TOKEN_PREFIX + token;
		}
		const timestamp = new Date().getTime();
		config.headers["appkey"] = sysConfig.APP_KEY;
		config.headers["timestamp"] = timestamp;
		let signStr = "";
		if (!sysConfig.REQUEST_CACHE && config.method == "get") {
			config.params = config.params || {};
			config.params["_"] = timestamp;
			signStr =
				sysConfig.APP_KEY +
				sysConfig.SIGN_KEY +
				timestamp +
				tool.objKeySort(config.params);
		}
		if (
			config.method == "post" ||
			config.method == "put" ||
			config.method == "delete"
		) {
			signStr =
				sysConfig.APP_KEY +
				sysConfig.SIGN_KEY +
				timestamp +
				JSON.stringify(config.data);
		}
		config.headers["signature"] = tool.crypto.MD5(signStr);
		Object.assign(config.headers, sysConfig.HEADERS);
		return config;
	},
	(error) => {
		return Promise.reject(error);
	}
);

// HTTP response 拦截器
axios.interceptors.response.use(
	(response) => {
		if (response.headers["x-refresh-token"]) {
			tool.data.set("TOKEN", response.headers["x-refresh-token"]);
		}
		return response;
	},
	(error) => {
		if (error.response) {
			if (error.response.status == 404) {
				ElNotification.error({
					title: "请求错误",
					message: "Status:404，正在请求不存在的服务器记录！",
				});
			} else if (error.response.status == 500) {
				ElNotification.error({
					title: "请求错误",
					message:
						error.response.data.message ||
						"Status:500，服务器发生错误！",
				});
			} else if (error.response.status == 401) {
				ElMessageBox.confirm(
					"当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。",
					"无权限访问",
					{
						type: "error",
						closeOnClickModal: false,
						showCancelButton:true,
						confirmButtonText: "重新登录",
					}
				)
					.then(() => {
						router.replace({ path: "/login" });
					})
					.catch(() => {});
			} else {
				ElNotification.error({
					title: "请求错误",
					message:
						error.response.data.message ||
						`Status:${error.response.status}，未知错误！`,
				});
			}
		} else {
			ElNotification.error({
				title: "请求错误",
				message: "请求服务器无响应！",
			});
		}

		return Promise.reject(error.response);
	}
);

var http = {
	/** get 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} params
	 * @param  {参数} config
	 */
	get: function (url, params = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: "get",
				url: url,
				params: params,
				...config,
			})
				.then((response) => {
					resolve(response.data);
				})
				.catch((error) => {
					reject(error);
				});
		});
	},

	/** post 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	post: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: "post",
				url: url,
				data: data,
				...config,
			})
				.then((response) => {
					resolve(response.data);
				})
				.catch((error) => {
					reject(error);
				});
		});
	},

	/** put 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	put: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: "put",
				url: url,
				data: data,
				...config,
			})
				.then((response) => {
					resolve(response.data);
				})
				.catch((error) => {
					reject(error);
				});
		});
	},

	/** patch 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	patch: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: "patch",
				url: url,
				data: data,
				...config,
			})
				.then((response) => {
					resolve(response.data);
				})
				.catch((error) => {
					reject(error);
				});
		});
	},

	/** delete 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	delete: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: "delete",
				url: url,
				data: data,
				...config,
			})
				.then((response) => {
					resolve(response.data);
				})
				.catch((error) => {
					reject(error);
				});
		});
	},

	/** jsonp 请求
	 * @param  {接口地址} url
	 * @param  {JSONP回调函数名称} name
	 */
	jsonp: function (url, name = "jsonp") {
		return new Promise((resolve) => {
			var script = document.createElement("script");
			var _id = `jsonp${Math.ceil(Math.random() * 1000000)}`;
			script.id = _id;
			script.type = "text/javascript";
			script.src = url;
			window[name] = (response) => {
				resolve(response);
				document.getElementsByTagName("head")[0].removeChild(script);
				try {
					delete window[name];
				} catch (e) {
					window[name] = undefined;
				}
			};
			document.getElementsByTagName("head")[0].appendChild(script);
		});
	},
};

export default http;
